#define round_pgup(_p) (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
#define round_pgdown(_p) ((_p)&PAGE_MASK)
-struct domain_setup_info
+static int probeimageformat(char *image,
+ unsigned long image_size,
+ struct load_funcs *load_funcs)
{
- unsigned long v_start;
- unsigned long v_end;
- unsigned long v_kernstart;
- unsigned long v_kernend;
- unsigned long v_kernentry;
-
- unsigned int load_symtab;
- unsigned long symtab_addr;
- unsigned long symtab_len;
-};
-
-static int
-parseelfimage(
- char *elfbase, unsigned long elfsize, struct domain_setup_info *dsi);
-static int
-loadelfimage(
- char *elfbase, int xch, u32 dom, unsigned long *parray,
- struct domain_setup_info *dsi);
-static int
-loadelfsymtab(
- char *elfbase, int xch, u32 dom, unsigned long *parray,
- struct domain_setup_info *dsi);
+ if ( probe_elf(image, image_size, load_funcs) &&
+ probe_bin(image, image_size, load_funcs) )
+ {
+ ERROR( "Unrecognized image format" );
+ return -EINVAL;
+ }
+
+ return 0;
+}
static int setup_guest(int xc_handle,
- u32 dom,
- char *image, unsigned long image_size,
- gzFile initrd_gfd, unsigned long initrd_len,
- unsigned long nr_pages,
- unsigned long *pvsi, unsigned long *pvke,
- vcpu_guest_context_t *ctxt,
- const char *cmdline,
- unsigned long shared_info_frame,
- unsigned int control_evtchn,
- unsigned long flags,
- unsigned int vcpus)
+ u32 dom,
+ char *image, unsigned long image_size,
+ gzFile initrd_gfd, unsigned long initrd_len,
+ unsigned long nr_pages,
+ unsigned long *pvsi, unsigned long *pvke,
+ unsigned long *pvss, vcpu_guest_context_t *ctxt,
+ const char *cmdline,
+ unsigned long shared_info_frame,
+ unsigned int control_evtchn,
+ unsigned long flags,
+ unsigned int vcpus,
+ unsigned int store_evtchn, unsigned long *store_mfn)
{
l1_pgentry_t *vl1tab=NULL, *vl1e=NULL;
l2_pgentry_t *vl2tab=NULL, *vl2e=NULL;
vpt_end = vpt_start + (nr_pt_pages * PAGE_SIZE);
vstartinfo_start = vpt_end;
vstartinfo_end = vstartinfo_start + PAGE_SIZE;
- vstack_start = vstartinfo_end;
+ /* Place store shared page after startinfo. */
+ vstoreinfo_start = vstartinfo_end;
+ vstoreinfo_end = vstartinfo_end + PAGE_SIZE;
+ vstack_start = vstoreinfo_end;
vstack_end = vstack_start + PAGE_SIZE;
- v_end = (vstack_end + (1<<22)-1) & ~((1<<22)-1);
- if ( (v_end - vstack_end) < (512 << 10) )
- v_end += 1 << 22; /* Add extra 4MB to get >= 512kB padding. */
+ v_end = (vstack_end + (1UL<<22)-1) & ~((1UL<<22)-1);
+ if ( (v_end - vstack_end) < (512UL << 10) )
+ v_end += 1UL << 22; /* Add extra 4MB to get >= 512kB padding. */
+#if defined(__i386__)
if ( (((v_end - dsi.v_start + ((1<<L2_PAGETABLE_SHIFT)-1)) >>
L2_PAGETABLE_SHIFT) + 1) <= nr_pt_pages )
break;
+#endif
+#if defined(__x86_64__)
+#define NR(_l,_h,_s) \
+ (((((_h) + ((1UL<<(_s))-1)) & ~((1UL<<(_s))-1)) - \
+ ((_l) & ~((1UL<<(_s))-1))) >> (_s))
+ if ( (1 + /* # L4 */
+ NR(dsi.v_start, v_end, L4_PAGETABLE_SHIFT) + /* # L3 */
+ NR(dsi.v_start, v_end, L3_PAGETABLE_SHIFT) + /* # L2 */
+ NR(dsi.v_start, v_end, L2_PAGETABLE_SHIFT)) /* # L1 */
+ <= nr_pt_pages )
+ break;
+#endif
}
+#define _p(a) ((void *) (a))
+
printf("VIRTUAL MEMORY ARRANGEMENT:\n"
- " Loaded kernel: %08lx->%08lx\n"
- " Init. ramdisk: %08lx->%08lx\n"
- " Phys-Mach map: %08lx->%08lx\n"
- " Page tables: %08lx->%08lx\n"
- " Start info: %08lx->%08lx\n"
- " Store page: %08lx->%08lx\n"
- " Boot stack: %08lx->%08lx\n"
- " TOTAL: %08lx->%08lx\n",
- dsi.v_kernstart, dsi.v_kernend,
- vinitrd_start, vinitrd_end,
- vphysmap_start, vphysmap_end,
- vpt_start, vpt_end,
- vstartinfo_start, vstartinfo_end,
- vstoreinfo_start, vstoreinfo_end,
- vstack_start, vstack_end,
- dsi.v_start, v_end);
- printf(" ENTRY ADDRESS: %08lx\n", dsi.v_kernentry);
+ " Loaded kernel: %p->%p\n"
+ " Init. ramdisk: %p->%p\n"
+ " Phys-Mach map: %p->%p\n"
+ " Page tables: %p->%p\n"
+ " Start info: %p->%p\n"
++ " Store page: %p->%p\n"
+ " Boot stack: %p->%p\n"
+ " TOTAL: %p->%p\n",
+ _p(dsi.v_kernstart), _p(dsi.v_kernend),
+ _p(vinitrd_start), _p(vinitrd_end),
+ _p(vphysmap_start), _p(vphysmap_end),
+ _p(vpt_start), _p(vpt_end),
+ _p(vstartinfo_start), _p(vstartinfo_end),
++ _p(vstoreinfo_start), _p(vstoreinfo_end),
+ _p(vstack_start), _p(vstack_end),
+ _p(dsi.v_start), _p(v_end));
+ printf(" ENTRY ADDRESS: %p\n", _p(dsi.v_kernentry));
if ( (v_end - dsi.v_start) > (nr_pages * PAGE_SIZE) )
{
start_info->mod_start = vinitrd_start;
start_info->mod_len = initrd_len;
}
- strncpy((char *)start_info->cmd_line, cmdline, MAX_CMDLINE);
- start_info->cmd_line[MAX_CMDLINE-1] = '\0';
+ strncpy((char *)start_info->cmd_line, cmdline, MAX_GUEST_CMDLINE);
+ start_info->cmd_line[MAX_GUEST_CMDLINE-1] = '\0';
munmap(start_info, PAGE_SIZE);
+ /* Tell our caller where we told domain store page was. */
+ *store_mfn = page_array[((vstoreinfo_start-dsi.v_start)>>PAGE_SHIFT)];
+
/* shared_info page starts its life empty. */
shared_info = xc_map_foreign_range(
xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE, shared_info_frame);
ctxt->user_regs.es = FLAT_KERNEL_DS;
ctxt->user_regs.fs = FLAT_KERNEL_DS;
ctxt->user_regs.gs = FLAT_KERNEL_DS;
- ctxt->user_regs.ss = FLAT_KERNEL_DS;
+ ctxt->user_regs.ss = FLAT_KERNEL_SS;
ctxt->user_regs.cs = FLAT_KERNEL_CS;
ctxt->user_regs.eip = vkern_entry;
- ctxt->user_regs.esp = vstartinfo_start + 2*PAGE_SIZE;
+ ctxt->user_regs.esp = vstack_start + PAGE_SIZE;
ctxt->user_regs.esi = vstartinfo_start;
ctxt->user_regs.eflags = 1 << 9; /* Interrupt Enable */
ctxt->gdt_ents = 0;
/* Ring 1 stack is the initial stack. */
- ctxt->kernel_ss = FLAT_KERNEL_DS;
+ ctxt->kernel_ss = FLAT_KERNEL_SS;
- ctxt->kernel_sp = vstartinfo_start + 2*PAGE_SIZE;
+ ctxt->kernel_sp = vstack_start + PAGE_SIZE;
/* No debugging. */
memset(ctxt->debugreg, 0, sizeof(ctxt->debugreg));
* extended by an extra 4MB to ensure this.
*/
-#define MAX_CMDLINE 256
+#define MAX_GUEST_CMDLINE 1024
typedef struct {
- /* THE FOLLOWING ARE FILLED IN BOTH ON INITIAL BOOT AND ON RESUME. */
- memory_t nr_pages; /* 0: Total pages allocated to this domain. */
- /* THE FOLLOWING ARE FILLED IN BOTH ON INITIAL BOOT AND ON RESUME. */
- memory_t nr_pages; /* 0: Total pages allocated to this domain. */
++ /* THE FOLLOWING ARE FILLED IN BOTH ON INITIAL BOOT AND ON RESUME. */
++ memory_t nr_pages; /* 0: Total pages allocated to this domain. */
_MEMORY_PADDING(A);
- memory_t shared_info; /* 8: MACHINE address of shared info struct.*/
- memory_t shared_info; /* 8: MACHINE address of shared info struct. */
++ memory_t shared_info; /* 8: MACHINE address of shared info struct. */
_MEMORY_PADDING(B);
- u32 flags; /* 16: SIF_xxx flags. */
- u32 flags; /* 16: SIF_xxx flags. */
++ u32 flags; /* 16: SIF_xxx flags. */
u16 domain_controller_evtchn; /* 20 */
u16 __pad;
- /* THE FOLLOWING ARE ONLY FILLED IN ON INITIAL BOOT (NOT RESUME). */
- memory_t pt_base; /* 24: VIRTUAL address of page directory. */
- /* THE FOLLOWING ARE ONLY FILLED IN ON INITIAL BOOT (NOT RESUME). */
- memory_t pt_base; /* 24: VIRTUAL address of page directory. */
++ /* THE FOLLOWING ARE ONLY FILLED IN ON INITIAL BOOT (NOT RESUME). */
++ memory_t pt_base; /* 24: VIRTUAL address of page directory. */
_MEMORY_PADDING(C);
- memory_t nr_pt_frames; /* 32: Number of bootstrap p.t. frames. */
- memory_t nr_pt_frames; /* 32: Number of bootstrap p.t. frames. */
++ memory_t nr_pt_frames; /* 32: Number of bootstrap p.t. frames. */
_MEMORY_PADDING(D);
- memory_t mfn_list; /* 40: VIRTUAL address of page-frame list. */
- memory_t mfn_list; /* 40: VIRTUAL address of page-frame list. */
++ memory_t mfn_list; /* 40: VIRTUAL address of page-frame list. */
_MEMORY_PADDING(E);
- memory_t mod_start; /* 48: VIRTUAL address of pre-loaded module. */
- memory_t mod_start; /* 48: VIRTUAL address of pre-loaded module. */
++ memory_t mod_start; /* 48: VIRTUAL address of pre-loaded module. */
_MEMORY_PADDING(F);
- memory_t mod_len; /* 56: Size (bytes) of pre-loaded module. */
- memory_t mod_len; /* 56: Size (bytes) of pre-loaded module. */
++ memory_t mod_len; /* 56: Size (bytes) of pre-loaded module. */
_MEMORY_PADDING(G);
- s8 cmd_line[MAX_CMDLINE]; /* 64 */
- memory_t store_page; /* 320: VIRTUAL address of store page. */
+ s8 cmd_line[MAX_GUEST_CMDLINE]; /* 64 */
- } PACKED start_info_t; /* 1088 bytes */
++ memory_t store_page; /* 1088: VIRTUAL address of store page. */
+ _MEMORY_PADDING(H);
- u16 store_evtchn; /* 328: Event channel for store communication. */
-} PACKED start_info_t; /* 332/336 bytes */
++ u16 store_evtchn; /* 1096: Event channel for store communication. */
++} PACKED start_info_t; /* 1098 bytes */
/* These flags are passed in the 'flags' field of start_info_t. */
#define SIF_PRIVILEGED (1<<0) /* Is the domain privileged? */